import { Alert, Space, Tabs, message, Image, Button, Input, Row, Col } from 'antd';
import {
  AlipayCircleOutlined,
  CloseOutlined,
  LockOutlined,
  MobileOutlined,
  SafetyCertificateOutlined,
  TaobaoCircleOutlined,
  UserOutlined,
  WeiboCircleOutlined,
} from '@ant-design/icons';
import { FormattedMessage, Link, SelectLang, history, useIntl, useModel } from 'umi';
import ProForm, { ProFormCaptcha, ProFormCheckbox, ProFormText } from '@ant-design/pro-form';
import React, { useRef, useState, useEffect } from 'react';

import EventComponent from '@/components/EventSource';
import Footer from '@/components/Footer';
import {
  postApiLoginAccount as login,
  getApiCaptcha as getFakeCaptcha,
  postApiLoginAccountTwoFactorVerify as twoFactorVerify
} from '@/services/furion-cms/Account';
import styles from './index.less';
import { Md5 } from 'ts-md5';
import type {
  ProFormInstance,
} from '@ant-design/pro-form';
import twoFactor from '@/asstes/twoFactorVerify.png';
import { CSSTransition, SwitchTransition } from 'react-transition-group';
// import './ReactTransitionSwitch.css'

const LoginMessage: React.FC<{
  content: string;
}> = ({ content }) => (
  <Alert
    style={{
      marginBottom: 24,
    }}
    message={content}
    type="error"
    showIcon
  />
);

const Login: React.FC = () => {
  const [submitting, setSubmitting] = useState(false);
  const [userLoginState, setUserLoginState] = useState<API.LoginResult>({});
  const [type, setType] = useState<string>('account');
  const [captchaTimestamp, setCaptchaTimestamp] = useState<number>(new Date().getTime());
  const [twoFactorVerifyVisible, setTwoFactorVerifyVisible] = useState(false);
  const [twoFactorVerifyPhone, setTwoFactorVerifyPhone] = useState<string>('');

  const { initialState, setInitialState } = useModel('@@initialState');
  const intl = useIntl();
  const formRef = useRef<ProFormInstance<Partial<API.LoginParams & { timestamp: number }>>>();
  const twoFactorFormRef = useRef<ProFormInstance<API.TwoFactorVerifyParams>>();

  useEffect(() => {
    formRef.current?.setFieldsValue({
      timestamp: captchaTimestamp
    });
  }, [captchaTimestamp]);

  const fetchUserInfo = async () => {
    const userInfo = await initialState?.fetchUserInfo?.();
    const eventHub = new EventComponent(); // 登录成功后立即与服务端事件集线器建立监听
    if (userInfo) {
      await setInitialState((s) => ({
        ...s,
        currentUser: userInfo,
        eventHub
      }));
    }
  };

  const handleLoginSuccessAfter = async () => {
    const defaultLoginSuccessMessage = intl.formatMessage({
      id: 'pages.login.success',
      defaultMessage: '登录成功!',
    });
    message.success(defaultLoginSuccessMessage);
    await fetchUserInfo();

    /** 此方法会跳转到 redirect 参数所在的位置 */
    if (!history) return;
    const { query } = history.location;
    const { redirect } = query as { redirect: string };
    history.push(redirect || '/admin');
  }

  const handleSubmit = async (values: API.LoginParams) => {
    setSubmitting(true);
    try {
      // 登录
      const msg = await login({ ...values, type });
      if (msg.data?.status === 'ok') {

        // 双因素验证处理
        if (msg.data.verifyPhoneNumber) {
          console.info('启用了双因素验证,准备开始');
          setTwoFactorVerifyPhone(msg.data.verifyPhoneNumber);
          setTwoFactorVerifyVisible(true);
          twoFactorFormRef.current?.resetFields();
        }
        else {
          handleLoginSuccessAfter();
        }
        return;
      }
      // 如果失败去设置用户错误信息
      setUserLoginState(msg.data || {});
    } catch (error) {
      const defaultLoginFailureMessage = intl.formatMessage({
        id: 'pages.login.failure',
        defaultMessage: '登录失败，请重试!',
      });
      message.error(defaultLoginFailureMessage);
    } finally {
      // 刷新验证码
      setCaptchaTimestamp(new Date().getTime());
      setSubmitting(false);
    }
  };
  const { type: loginType, status, resultMessage } = userLoginState;

  return (
    <div className={styles.container}>
      <div className={styles.lang} data-lang>
        {SelectLang && <SelectLang />}
      </div>
      <div className={styles.content}>
        <div className={styles.top}>
          <div className={styles.header}>
            <Link to="/">
              <img alt="logo" className={styles.logo} src={initialState?.settings?.logo} />
              <span className={styles.title}>{initialState?.settings?.name}</span>
            </Link>
          </div>
          <div className={styles.desc}>
            {initialState?.settings?.description}
          </div>
        </div>

        <div className={styles.main}>
          <SwitchTransition mode="out-in">
            <CSSTransition classNames={{
              enter: styles.alertEnter,
              enterActive: styles.alertEnterActive,
              exit: styles.alertExit,
              exitActive: styles.alertExitActive
            }} timeout={300} key={(!twoFactorVerifyVisible) ? "on" : "off"}>
              {twoFactorVerifyVisible ? <ProForm<API.TwoFactorVerifyParams>
                onFinish={async (values) => {
                  setSubmitting(true);
                  try {
                    await twoFactorVerify(values);
                    handleLoginSuccessAfter()
                  } catch { }
                  setSubmitting(false);
                }}
                formRef={twoFactorFormRef}
                submitter={false}
                autoFocusFirstInput
              >
                <div className={styles.twoFactor}>
                  <h2>短信安全码验证</h2>
                  <Button type="text" className={styles.twoFactorFormClose} icon={<CloseOutlined />}
                    onClick={() => {
                      setTwoFactorVerifyVisible(false);
                      setSubmitting(false);
                      setCaptchaTimestamp(new Date().getTime());
                      formRef.current?.resetFields();
                    }} />
                  <Image src={twoFactor} width={110} height={136} preview={false} />
                </div>
                <Input.Group compact>
                  <ProFormText name="captcha"
                    placeholder={intl.formatMessage({
                      id: 'pages.login.captcha.placeholder',
                      defaultMessage: '请输入验证码!',
                    })}
                    fieldProps={{
                      size: 'large',
                      prefix: <SafetyCertificateOutlined className={styles.prefixIcon} />,
                      className: submitting ? styles.twoFactorSubmitLoading : styles.twoFactorSubmit
                    }}
                    rules={[
                      {
                        required: true,
                        message: intl.formatMessage({
                          id: 'pages.login.captcha.required',
                          defaultMessage: '验证码是必填项！'
                        }),
                      },
                    ]}
                    noStyle />
                  <ProFormText name="phoneNumber" initialValue={twoFactorVerifyPhone} hidden disabled />
                  <Button type="primary" size="large" loading={submitting ? {
                    delay: 200
                  } : false}
                    onClick={() => {
                      twoFactorFormRef.current?.validateFieldsReturnFormatValue?.()
                        .then((values) => {
                          console.log('双因素验证值-success', values, twoFactorVerifyPhone);
                          twoFactorFormRef.current?.submit();
                        })
                        .catch(({ values, errorFields }) => {
                          console.log('双因素验证值-fail', values, errorFields, twoFactorVerifyPhone);
                          message.error(errorFields[0].errors[0]);
                        });
                    }} >提交验证</Button>
                </Input.Group>
              </ProForm> :
                <>
                  <ProForm
                    initialValues={{
                      autoLogin: true,
                    }}
                    submitter={{
                      searchConfig: {
                        submitText: intl.formatMessage({
                          id: 'pages.login.submit',
                          defaultMessage: '登录',
                        }),
                      },
                      render: (_, dom) => [dom.pop()],
                      submitButtonProps: {
                        loading: submitting,
                        size: 'large',
                        style: {
                          width: '100%',
                        },
                      },
                    }}
                    onFinish={async (values) => {
                      await handleSubmit(values as API.LoginParams);
                    }}
                    isKeyPressSubmit={true}
                    formRef={formRef}
                  >
                    {initialState?.settings?.isPhoneNumberLogin ?
                      <Tabs activeKey={type} onChange={(activeKey) => {
                        setType(activeKey);
                        setUserLoginState({});
                        setCaptchaTimestamp(new Date().getTime());
                        formRef.current?.resetFields();
                      }}>
                        <Tabs.TabPane
                          key="account"
                          tab={intl.formatMessage({
                            id: 'pages.login.accountLogin.tab',
                            defaultMessage: '账户密码登录',
                          })}
                        />
                        <Tabs.TabPane
                          key="mobile"
                          tab={intl.formatMessage({
                            id: 'pages.login.phoneLogin.tab',
                            defaultMessage: '手机号登录',
                          })}
                        />
                      </Tabs> : ''}


                    {status === 'error' && loginType === 'account' && (
                      <LoginMessage
                        content={resultMessage || '登录失败，请重试!'}
                      />
                    )}
                    {type === 'account' && (
                      <>
                        <ProFormText
                          name="username"
                          fieldProps={{
                            size: 'large',
                            prefix: <UserOutlined className={styles.prefixIcon} />,
                          }}
                          placeholder={intl.formatMessage({
                            id: 'pages.login.username.placeholder',
                            defaultMessage: '用户名',
                          })}
                          rules={[
                            {
                              required: true,
                              message: (
                                <FormattedMessage
                                  id="pages.login.username.required"
                                  defaultMessage="请输入用户名!"
                                />
                              ),
                            },
                          ]}
                        />
                        <ProFormText.Password
                          name="password"
                          fieldProps={{
                            size: 'large',
                            prefix: <LockOutlined className={styles.prefixIcon} />,
                          }}
                          placeholder={intl.formatMessage({
                            id: 'pages.login.password.placeholder',
                            defaultMessage: '密码',
                          })}
                          rules={[
                            {
                              required: true,
                              message: (
                                <FormattedMessage
                                  id="pages.login.password.required"
                                  defaultMessage="请输入密码!"
                                />
                              ),
                            },
                          ]}
                          transform={(value: any, field: string, object: API.LoginParams) => {
                            object[field] = Md5.hashStr(value);
                            return object;
                          }}
                        />
                        {/* 验证码启用控制 */}
                        {initialState?.settings?.isLoginCaptcha &&
                          <>
                            <ProFormText name="timestamp" initialValue={captchaTimestamp} hidden />
                            <Row wrap={false}>
                              <Col flex="auto">
                                <ProFormText
                                  name="captcha"
                                  fieldProps={{
                                    size: 'large',
                                    prefix: <SafetyCertificateOutlined className={styles.prefixIcon} />,
                                  }}
                                  placeholder={intl.formatMessage({
                                    id: 'pages.login.captcha.placeholder',
                                    defaultMessage: '请输入验证码!',
                                  })}
                                  rules={[
                                    {
                                      required: true,
                                      message: intl.formatMessage({
                                        id: 'pages.login.captcha.required',
                                        defaultMessage: '验证码是必填项！'
                                      }),
                                    },
                                  ]}
                                />
                              </Col>
                              <Col flex="110px" style={{
                                textAlign: 'right'
                              }}>
                                <Image src={`/api/captcha/graphic?timestamp=${captchaTimestamp}`}
                                  height={40} width={100} preview={false} style={{ cursor: 'pointer' }}
                                  onClick={() => setCaptchaTimestamp(new Date().getTime())}
                                  loading="lazy" />
                              </Col>
                            </Row>
                          </>
                        }
                      </>
                    )}

                    {status === 'error' && loginType === 'mobile' && <LoginMessage content={resultMessage || '手机号验证失败'} />}
                    {type === 'mobile' && (
                      <>
                        <ProFormText
                          fieldProps={{
                            size: 'large',
                            prefix: <MobileOutlined className={styles.prefixIcon} />,
                          }}
                          name="mobile"
                          placeholder={intl.formatMessage({
                            id: 'pages.login.phoneNumber.placeholder',
                            defaultMessage: '手机号',
                          })}
                          rules={[
                            {
                              required: true,
                              message: (
                                <FormattedMessage
                                  id="pages.login.phoneNumber.required"
                                  defaultMessage="请输入手机号!"
                                />
                              ),
                            },
                            {
                              pattern: /^1\d{10}$/,
                              message: (
                                <FormattedMessage
                                  id="pages.login.phoneNumber.invalid"
                                  defaultMessage="手机号格式错误!"
                                />
                              ),
                            },
                          ]}
                        />
                        <ProFormCaptcha
                          fieldProps={{
                            size: 'large',
                            prefix: <LockOutlined className={styles.prefixIcon} />,
                          }}
                          captchaProps={{
                            size: 'large',
                          }}
                          placeholder={intl.formatMessage({
                            id: 'pages.login.captcha.placeholder',
                            defaultMessage: '请输入验证码',
                          })}
                          captchaTextRender={(timing, count) => {
                            if (timing) {
                              return `${count} ${intl.formatMessage({
                                id: 'pages.getCaptchaSecondText',
                                defaultMessage: '获取验证码',
                              })}`;
                            }
                            return intl.formatMessage({
                              id: 'pages.login.phoneLogin.getVerificationCode',
                              defaultMessage: '获取验证码',
                            });
                          }}
                          name="captcha"
                          phoneName="mobile"
                          rules={[
                            {
                              required: true,
                              message: (
                                <FormattedMessage
                                  id="pages.login.captcha.required"
                                  defaultMessage="请输入验证码!"
                                />
                              ),
                            },
                          ]}
                          onGetCaptcha={async (phone) => {
                            console.log(`sendPhone:${phone}`);
                            try {
                              await getFakeCaptcha({ phone });
                              message.success('获取验证码成功!验证码为:1234');
                            } catch (error) {

                            }
                          }}
                        />
                      </>
                    )}
                    <div
                      style={{
                        marginBottom: 24,
                      }}
                    >
                      <ProFormCheckbox noStyle name="autoLogin">
                        <FormattedMessage id="pages.login.rememberMe" defaultMessage="自动登录" />
                      </ProFormCheckbox>
                      <a
                        style={{
                          float: 'right',
                        }}
                      >
                        <FormattedMessage id="pages.login.forgotPassword" defaultMessage="忘记密码" />
                      </a>
                    </div>
                  </ProForm>
                  <Space className={styles.other}>
                    <FormattedMessage id="pages.login.loginWith" defaultMessage="其他登录方式" />
                    <AlipayCircleOutlined className={styles.icon} />
                    <TaobaoCircleOutlined className={styles.icon} />
                    <WeiboCircleOutlined className={styles.icon} />
                  </Space>
                </>}
            </CSSTransition>
          </SwitchTransition>



        </div>
      </div>
      <Footer />
    </div>
  );
};

export default Login;
